#pragma once

#include "../dependencies/mysql/mysql.h"
#include <string>
#include <vector>
#include <stdexcept>

namespace mysql {

    class MysqlResult {

    public:

        /**
          * @brief  构造函数接收预处理语句对象
          * @note   请勿拷贝该对象，浅拷贝可能会引发多重释放问题
          */
        explicit MysqlResult(MYSQL_STMT *stmt);

        /**
          * @brief  析构函数
          * @note   该函数将销毁结果集所有数据成员
          */
        ~MysqlResult();

        /**
          * @brief  调整结果行指向下一行
          * @retval 下一行是否为空
          */
        bool next();

        /**
          * @brief  获取指定列的字符串数据
          * @param  定列的索引
          * @retval 字符串数据
          */
        std::string getString(int column) const;

        /**
          * @brief  获取指定列的整形数据
          * @param  column 指定列
          * @retval 整形数据
          */
        int getInt(int column) const;

        /**
          * @brief  检查指定列是否为空值
          * @param  column 指定列的索引
          * @retval 是否为空值
          */
        bool isNull(int column) const { return *bind_[column].is_null == 1; }

        /**
          * @brief  获取列名
          * @param  column 列索引
          * @retval 列名
          */
        std::string getColumnName(int column) const;

        /**
          * @brief  获取结果集的列数
          * @retval 结果集的列数
          */
        unsigned long getColumnCount() const { return mysql_num_fields(result_); }

        /**
          * @brief  获取结果集的行数
          * @retval 结果集的行数
          */
        unsigned long getRowCount() const { return mysql_stmt_num_rows(stmt_); }

    private:

        /**
          * @brief  将MYSQL_TIME时间类型转换为字符串
          * @note   默认按照xxxx-xx-xx xx:xx:xx格式进行转换
          * @param  MYSQL_TIME结构体指针
          * @retval 转换后的字符串
          */
        static std::string timeToString(MYSQL_TIME *);

        // 预处理语句对象
        MYSQL_STMT *stmt_;

        // 结果元数据
        MYSQL_RES *result_;

        // 当前行数据
        MYSQL_BIND *bind_;

    };

}